package com.imis.module.system.bus;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.enums.ArgumentResponseEnum;
import com.imis.base.globle.response.BaseResponse;
import com.imis.base.globle.response.CommonResponse;
import com.imis.base.util.ConvertUtils;
import com.imis.module.base.BaseBus;
import com.imis.module.system.model.converter.SysMenuConverter;
import com.imis.module.system.model.po.SysMenu;
import com.imis.module.system.model.po.SysRole;
import com.imis.module.system.model.ro.PagingQueryMenuDTO;
import com.imis.module.system.model.ro.QueryMenuDTO;
import com.imis.module.system.model.ro.SysMenuAddRO;
import com.imis.module.system.model.ro.SysMenuUpdateRO;
import com.imis.module.system.model.vo.SysMenuTreeVO;
import com.imis.module.system.model.vo.SysMenuVO;
import com.imis.module.system.service.ISysMenuService;
import com.imis.module.system.service.ISysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 功能菜单表 业务处理类
 * </p>
 *
 * @author XinLau
 * @since 2020-03-17
 */
@Service
public class SysMenuBus extends BaseBus {

    /**
     * 功能菜单表 服务类
     */
    private ISysMenuService serviceBySysMenuService;

    @Autowired
    public void setServiceBySysMenuService(ISysMenuService serviceBySysMenuService) {
        this.serviceBySysMenuService = serviceBySysMenuService;
    }

    /**
     * 系统角色表 服务类
     */
    private ISysRoleService sysRoleService;

    @Autowired
    public void setSysRoleService(ISysRoleService sysRoleService) {
        this.sysRoleService = sysRoleService;
    }

    /**
     * 添加功能菜单重复校验
     *
     * @param sysMenuAdd - 功能菜单添加对象
     * @return SysMenu - 功能菜单
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysMenu menuAddVerification(final SysMenuAddRO sysMenuAdd) {
        // 父级ID存在校验
        Long parentId = sysMenuAdd.getParentId();
        if (ConvertUtils.isNotEmpty(parentId) && parentId != 0) {
            SysMenu sysMenuParent = this.serviceBySysMenuService.getById(parentId);
            // 1.根据父级功能菜单信息查询，该父级功能菜单名不存在
            ArgumentResponseEnum.MENU_ADD_ERR_REPEAT.assertNotNull(sysMenuParent, sysMenuParent.getName());
            // 2.根据父级功能菜单信息查询，该父级功能菜单被删除
            ArgumentResponseEnum.MENU_ADD_ERR_DELETE.assertIsTrue(CommonConstant.DEL_FLAG_NOT_DELETE.equals(sysMenuParent.getDelFlag()), sysMenuParent.getName());
        }
        SysMenu sysMenu = this.serviceBySysMenuService.queryMenuByName(sysMenuAdd.getName());
        if (ConvertUtils.isNotEmpty(sysMenu)) {
            // 1.根据功能菜单信息查询，该功能菜单被删除
            ArgumentResponseEnum.MENU_ADD_ERR_DELETE.assertIsTrue(CommonConstant.DEL_FLAG_NOT_DELETE.equals(sysMenu.getDelFlag()), sysMenu.getName());
            // 2.根据功能菜单信息查询，该功能菜单名存在
            ArgumentResponseEnum.MENU_ADD_ERR_REPEAT.assertIsNull(sysMenu, sysMenu.getName());
        }
        return SysMenuConverter.INSTANCE.getAddEntity(sysMenuAdd);
    }

    /**
     * 删除功能菜单校验
     *
     * @param menuIdentification - 功能菜单对象编号
     * @return SysMenu - 功能菜单
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    private SysMenu menuDeleteVerification(final Long menuIdentification) {
        SysMenu sysMenu = this.serviceBySysMenuService.getById(menuIdentification);
        // 1.根据功能菜单信息查询，该功能菜单不存在
        ArgumentResponseEnum.MENU_DELETE_ERR_NON.assertNotNull(sysMenu);
        // 判断功能菜单是否分配给角色
        Long[] sysRoleIdArray = this.serviceBySysMenuService.selectSysRoleIdArrayByMenuId(sysMenu.getId());
        ArgumentResponseEnum.MENU_DELETE_ERR_ASSIGNED.assertNotEmpty(sysRoleIdArray, sysMenu.getName());
        // 判断功能菜单旗下是否存在子级功能菜单
        List<SysMenuVO> sysMenuChildList = this.serviceBySysMenuService.selectSysMenuListByParentId(sysMenu.getId());
        ArgumentResponseEnum.MENU_DELETE_ERR_HAVE_CHILD.assertNotEmpty(sysMenuChildList, sysMenu.getName());
        return sysMenu;
    }

    /**
     * 功能菜单更新校验
     *
     * @param sysMenuUpdate - 功能菜单更新对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    private SysMenu menuUpdateVerification(final SysMenuUpdateRO sysMenuUpdate) {
        SysMenu sysMenu = this.serviceBySysMenuService.getById(sysMenuUpdate.getId());
        // 1.根据功能菜单信息查询，该功能菜单不存在
        ArgumentResponseEnum.MENU_UPDATE_ERR_NON.assertNotNull(sysMenu, sysMenuUpdate.getName());
        // 2.功能菜单名重复校验
        if (!sysMenu.getName().equals(sysMenuUpdate.getName())) {
            SysMenu menuByName = this.serviceBySysMenuService.queryMenuByName(sysMenuUpdate.getName());
            ArgumentResponseEnum.MENU_UPDATE_ERR_REPEAT.assertIsNull(menuByName, sysMenuUpdate.getName());
        }
        SysMenuConverter.INSTANCE.getUpdateEntity(sysMenu, sysMenuUpdate);
        return sysMenu;
    }

    /**
     * 分页查询功能菜单
     *
     * @param pagingQueryMenuDTO - 功能菜单查询对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public CommonResponse<Page<SysMenuTreeVO>> pagingQuerySysMenuParentListByParameter(PagingQueryMenuDTO pagingQueryMenuDTO) {
        Page<SysMenuTreeVO> sysMenuParentListByParameter = this.serviceBySysMenuService.pagingQuerySysMenuParentListByParameter(pagingQueryMenuDTO);
        return new CommonResponse<>(sysMenuParentListByParameter);
    }

    /**
     * 查询功能菜单树接口
     *
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public CommonResponse<List<SysMenuTreeVO>> querySysMenuTreeListByParameter(QueryMenuDTO queryMenuDTO) {
        List<SysMenuTreeVO> sysMenuTreeVOList = this.serviceBySysMenuService.querySysMenuTreeListByParameter(queryMenuDTO);
        return new CommonResponse<>(sysMenuTreeVOList);
    }

    /**
     * 功能菜单添加
     *
     * @param sysMenuAdd - 功能菜单添加对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public BaseResponse addMenu(final SysMenuAddRO sysMenuAdd) {
        // 1.校验功能菜单名重复
        SysMenu sysMenu = this.menuAddVerification(sysMenuAdd);
        boolean saveMenu = this.serviceBySysMenuService.save(sysMenu);
        // 2.判断保存成功
        ArgumentResponseEnum.MENU_ADD_ERR.assertIsTrue(saveMenu, sysMenuAdd.getName());
        return new CommonResponse<>();
    }

    /**
     * 功能菜单删除
     *
     * @param menuIdentification - 功能菜单标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public BaseResponse deleteMenu(final Long menuIdentification) {
        // 1.删除功能菜单校验
        SysMenu sysMenu = this.menuDeleteVerification(menuIdentification);
        ArgumentResponseEnum.MENU_DELETE_ERR_NON.assertNotNull(sysMenu, menuIdentification);
        // 2.删除功能菜单
        boolean deleteMenu = this.serviceBySysMenuService.deleteMenuById(menuIdentification);
        // 3.判断删除成功
        ArgumentResponseEnum.MENU_DELETE_ERR.assertIsTrue(deleteMenu, menuIdentification);
        return new CommonResponse<>();
    }

    /**
     * 功能菜单查看
     *
     * @param menuIdentification - 功能菜单标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public CommonResponse<SysMenuVO> queryMenuById(final Long menuIdentification) {
        SysMenu sysMenu = this.serviceBySysMenuService.getById(menuIdentification);
        // 1.根据功能菜单信息查询，该功能菜单不存在
        ArgumentResponseEnum.MENU_QUERY_ERR.assertNotNull(sysMenu);
        return new CommonResponse<>(SysMenuConverter.INSTANCE.getReturnValue(sysMenu));
    }

    /**
     * 功能菜单更新
     *
     * @param sysMenuUpdate - 功能菜单更新对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public BaseResponse updateMenu(final SysMenuUpdateRO sysMenuUpdate) {
        // 1.更新菜单校验
        SysMenu sysMenu = this.menuUpdateVerification(sysMenuUpdate);
        // 2.功能菜单更新
        boolean updateMenu = this.serviceBySysMenuService.updateByMenuIdentification(sysMenu);
        // 3.判断保存成功
        ArgumentResponseEnum.MENU_UPDATE_ERR.assertIsTrue(updateMenu, sysMenuUpdate.getName());
        return new CommonResponse<>();
    }

    /**
     * 查看角色拥有功能菜单接口
     *
     * @param roleIdentification - 角色标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public CommonResponse<List<SysMenuTreeVO>> querySysMenuTreeListByRoleId(final Long roleIdentification) {
        // 1.校验角色
        SysRole sysRole = this.sysRoleService.getById(roleIdentification);
        ArgumentResponseEnum.MENU_TREE_QUERY_ERR_ROLE_NON.assertNotNull(sysRole);
        // 2.查询角色拥有功能菜单
        List<SysMenuTreeVO> sysMenuTreeListByRoleId = this.serviceBySysMenuService.querySysMenuTreeListByRoleId(roleIdentification);
        return new CommonResponse<>(sysMenuTreeListByRoleId);
    }

}